Conversation
Add `Linking.openNotificationSettings()` which opens the app's notification settings screen in the system Settings app. - iOS: uses `UIApplicationOpenNotificationSettingsURLString` (iOS 15.4+), falling back to `UIApplicationOpenSettingsURLString` on 15.1-15.3. - Android: launches `Settings.ACTION_APP_NOTIFICATION_SETTINGS` with `Settings.EXTRA_APP_PACKAGE` (API 26+), falling back to `ACTION_APPLICATION_DETAILS_SETTINGS` on API 24-25. Includes TurboModule spec entries, legacy and generated TS types, ReactAndroid.api entry, jest-preset mock, RNTester example, a JS dispatch test and Robolectric tests for the Android module. Changelog: [GENERAL] [ADDED] - Add Linking.openNotificationSettings() to open the app's notification settings on iOS (15.4+) and Android (API 26+), falling back to the app settings page on older OS versions Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Warning JavaScript API change detected This PR commits an update to
This change was flagged as: |
|
This PR introduces a new API that we would have to maintain in the future. This might need further discussion even if the change is per se small. I wonder if we would actually need a more generic API that allows the user to chose where to land in the setting page. I know that Apple only offer a subset of targets, so it might be a bit trickier to implement. WDYT? |
|
Thanks for getting back at this so quickly @cipolleschi ! Agree it is worth deciding the shape before adding surface. I went with a separate method because it maps one-to-one onto what the platforms offer: Apple ships On the generic option, the constraint is Apple: there are exactly three public, App-Review-safe Settings URLs ( But if you would prefer not adding a new method, we could extend the existing one with a closed, typed union covering only destinations both platforms support officially:
Happy to rework this PR to that shape, with notifications only and defaultApps as the documented next value, or to include both. Let me know which way to go! |
Summary:
Linking.openSettings()opens Settings → Your App. Both platforms have had an official, App-Review-safe way to land one level deeper, on the app's notification settings, for years, but React Native does not expose either:UIApplication.openNotificationSettingsURLStringSettings.ACTION_APP_NOTIFICATION_SETTINGSwithSettings.EXTRA_APP_PACKAGEToday apps either reach for undocumented
prefs:root=/App-Prefs:URLs on iOS (a known App Store rejection risk), or hand-rollLinking.sendIntenton Android (the existing RNTester Linking example does exactly this). Sending users to the right screen after a denied notification permission is a very common flow, so this belongs in core next toopenSettings(), which was added the same way in #23965.This PR adds
Linking.openNotificationSettings(): Promise<void>:UIApplicationOpenNotificationSettingsURLStringon iOS 15.4+, guarded with@availablesince the minimum deployment target is 15.1. On 15.1–15.3 it falls back toUIApplicationOpenSettingsURLString. TheopenURL+ resolve/reject logic is shared withopenSettingsvia a small private helper.ACTION_APP_NOTIFICATION_SETTINGSwithEXTRA_APP_PACKAGEon API 26+, and falls back toACTION_APPLICATION_DETAILS_SETTINGSon API 24–25. Intent flags matchopenSettings. The shared intent-building / activity-start code is factored into private helpers reused byopenSettings.Linking, TurboModule spec entries forNativeLinkingManagerandNativeIntentAndroid, legacy.d.tstypes, regeneratedReactNativeApi.d.tssnapshot,ReactAndroid.apientry, jest-preset mock, RNTester example.Linking-test.jscovering platform dispatch foropenSettings/openNotificationSettings; new Robolectric tests inIntentModuleTestcovering the API 26+ intent, the API 25 fallback (@Config(sdk = [25])), and rejection when there is no current activity.Fallback rather than rejection on old OS versions was chosen deliberately: callers want "take the user as close as possible to the notification toggle", and the general app settings page is that on those OS versions. Behavior is documented in the JSDoc.
Changelog:
[GENERAL] [ADDED] - Add
Linking.openNotificationSettings()to open the app's notification settings on iOS (15.4+) and Android (API 26+), falling back to the app settings page on older OS versionsTest Plan:
All run locally on macOS (Xcode 26.3, Zulu JDK 17, Node 22.23) against
main:Android (RNTester, Pixel 9 Pro API 35 emulator): built and installed via
:packages:rn-tester:android:app:installDebug. Linking → "Open notification settings" → Settings opens directly onSettings$AppNotificationSettingsActivityfor RNTester.iOS (RNTester, iPhone 17 Pro, iOS 26.3 simulator): built via
xcodebuild -workspace RNTesterPods.xcworkspace -scheme RNTester, no warnings fromRCTLinkingManager.mm. CallingLinking.openNotificationSettings()brings the Settings app to the foreground and the promise resolves. Note: on the iOS Simulator bothopenSettings()andopenNotificationSettings()land on the Settings root screen (the Simulator's Settings app does not expose third-party app pages), so the exact landing page could only be confirmed on Android; on a device iOS 15.4+ resolvesUIApplicationOpenNotificationSettingsURLStringto Settings → App → Notifications per Apple's documentation.Not tested: the iOS 15.1–15.3 and Android API 24–25 fallback paths on a device/emulator (no such runtimes available locally); the Android fallback is covered by the
@Config(sdk = [25])Robolectric test.